package com.zmc.member.infrastructure.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson2.JSONArray;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.zmc.common.constant.CacheConstants;
import com.zmc.common.utils.StringUtils;
import com.zmc.member.infrastructure.dao.AreaInfoDao;
import com.zmc.member.infrastructure.entity.AreaInfoEntity;
import com.zmc.member.infrastructure.service.AreaInfoService;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import java.util.List;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;


/**
 * @author zmc
 */
@Service("areaInfoService")
public class AreaInfoServiceImpl extends ServiceImpl<AreaInfoDao, AreaInfoEntity> implements AreaInfoService {

   @Autowired
   private RedissonClient redissonClient;

   @Autowired
   private StringRedisTemplate stringRedisTemplate;


    @Override
    public List<AreaInfoEntity> getChildrenByParentCode(String parentCode) {
        String infos = stringRedisTemplate.opsForValue().get(CacheConstants.AREA_ADDRESS_KEY + parentCode);
        if (StringUtils.isEmpty(infos)) {
            RLock lock = redissonClient.getLock(CacheConstants.AREA_ADDRESS_LOCK + parentCode);
            try{
                lock.lock();
                infos = stringRedisTemplate.opsForValue().get(CacheConstants.AREA_ADDRESS_KEY + parentCode);
                if (StringUtils.isEmpty(infos)) {
                    LambdaQueryWrapper<AreaInfoEntity> wrapper = new LambdaQueryWrapper<>();
                    wrapper.eq(AreaInfoEntity::getParentCode, parentCode);
                    List<AreaInfoEntity> list = list(wrapper);
                    stringRedisTemplate.opsForValue().set(CacheConstants.AREA_ADDRESS_KEY + parentCode, JSON.toJSONString(list));
                    return list;
                }
            } finally {
                lock.unlock();
            }

        }
        return JSONArray.parseArray(infos, AreaInfoEntity.class);
    }

    @Override
    public List<AreaInfoEntity> getListByCodes(List<String> address) {
        LambdaQueryWrapper<AreaInfoEntity> wrapper = new LambdaQueryWrapper<>();
        wrapper.in(AreaInfoEntity::getCode, address);
        return list(wrapper);
    }

    @Override
    public AreaInfoEntity getParentsCode(String code) {
        LambdaQueryWrapper<AreaInfoEntity> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(AreaInfoEntity::getCode, code);
        return getOne(wrapper);
    }
}